/*******************************************
 * Author : hanxianming
 * Date   : 2016-3-23
 * Use    : 
 *******************************************/

package plugin
{
    import fairygui.editor.plugin.ICallback;
    import fairygui.editor.plugin.IFairyGUIEditor;
    import fairygui.editor.plugin.IPublishData;
    import fairygui.editor.plugin.IPublishHandler;
    import fairygui.editor.publish.PublishData;
    import fairygui.editor.publish.gencode.GenCodeUtils;
    import fairygui.editor.utils.UtilsFile;
    import fairygui.editor.utils.UtilsStr;

    import flash.filesystem.File;

    public final class AutoGenerateCodePlugin implements IPublishHandler
	{
		private var _editor:IFairyGUIEditor;

        protected var settings:Object;
        protected var thisPackageFolder:File;
        protected var thisPackageName:String = "";
        protected var thisPackagePath:String = "";
        protected var sortedClasses:Array = [];
        protected var classInfo:Object;

        public var publishData:IPublishData;
        public var stepCallback:ICallback;

        public function AutoGenerateCodePlugin(editor:IFairyGUIEditor)
		{
			_editor = editor;
		}

		public function doExport(data:IPublishData, callback:ICallback):Boolean
		{
            publishData = data;
            stepCallback = callback;
            init("lua");
            loadTemplate("CSharp");

			callback.callOnSuccess();
			return true;
		}

        protected function init(fileExtName:String) : void
        {
            var path:String = null;
            var targetFolder:File = null;
            var oldFiles:Array = null;
            var file:File = null;
            var fileContent:String = null;
            var project:Object = publishData['_project'];
            this.settings = project.settingsCenter.publish;
            try
            {
                path = this.settings.codePath;
                path = UtilsStr.formatStringByName(path,project.customProperties);
                targetFolder = new File(project.basePath).resolvePath(path);
                if(!targetFolder.exists)
                {
                    targetFolder.createDirectory();
                }
                else if(!targetFolder.isDirectory)
                {
                    stepCallback.addMsg("Invalid code path!");
                    stepCallback.callOnFail();
                    return;
                }
            }
            catch(err:Error)
            {
                stepCallback.addMsg("Invalid code path!");
                stepCallback.callOnFail();
                return;
            }
            this.thisPackageName = PinYinUtils.toPinyin(publishData.targetUIPackage.name,false,false,false);
            this.thisPackageFolder = new File(targetFolder.nativePath + File.separator + this.thisPackageName);
            if(!this.settings.packageName || this.settings.packageName.length == 0)
            {
                this.thisPackagePath = this.thisPackageName;
            }
            else
            {
                this.thisPackagePath = this.settings.packageName + "." + this.thisPackageName;
            }
            if(this.thisPackageFolder.exists)
            {
                oldFiles = this.thisPackageFolder.getDirectoryListing();
                for each(file in oldFiles)
                {
                    if(!(file.isDirectory || file.extension != fileExtName))
                    {
                        fileContent = UtilsFile.loadString(file);
                        if(UtilsStr.startsWith(fileContent,GenCodeUtils.FILE_MARK))
                        {
                            UtilsFile.deleteFile(file);
                        }
                    }
                }
            }
            else
            {
                this.thisPackageFolder.createDirectory();
            }
            GenCodeUtils.prepare(publishData as PublishData);
            for each(this.classInfo in publishData.outputClasses)
            {
                if(!this.classInfo.ignored)
                {
                    this.classInfo.desc = publishData.outputDesc[classInfo.classId + ".xml"];
                    this.sortedClasses.push(this.classInfo);
                }
            }
            this.sortedClasses.sortOn("classId");
        }

        protected function loadTemplate(param1:String) : void
        {
            var _loc3_:Object = null;
            var project:Object = publishData['project'];
            var _loc2_:File = new File(project.basePath + "/template/" + param1);
            if(_loc2_.exists)
            {
                _loc3_ = this.loadTemplate2(_loc2_);
                if(_loc3_["Binder"] && _loc3_["Component"])
                {
                    this.createFile(_loc3_);
                    return;
                }
            }
            _loc2_ = File.applicationDirectory.resolvePath("template/" + param1);
            _loc3_ = this.loadTemplate2(_loc2_);
            this.createFile(_loc3_);
        }

        private function loadTemplate2(param1:File) : Object
        {
            var _loc4_:File = null;
            var _loc5_:String = null;
            var _loc2_:Array = param1.getDirectoryListing();
            var _loc3_:Object = {};
            for each(_loc4_ in _loc2_)
            {
                if(_loc4_.extension == "template")
                {
                    _loc5_ = _loc4_.name.replace(".template","");
                    _loc3_[_loc5_] = UtilsFile.loadString(_loc4_);
                }
            }
            return _loc3_;
        }

        protected function createFile(param1:*) : void
        {
            var _loc3_:* = null;
            var _loc4_:String = null;
            var _loc5_:Array = null;
            var _loc6_:Array = null;
            var _loc7_:String = null;
            var _loc8_:int = 0;
            var _loc9_:int = 0;
            var _loc10_:int = 0;
            var _loc2_:Array = [];
            for each(classInfo in sortedClasses)
            {
                _loc5_ = [];
                _loc6_ = [];
                _loc7_ = param1["Component"];
                _loc7_ = _loc7_.replace("{packageName}",thisPackagePath);
                _loc7_ = _loc7_.split("{className}").join(classInfo.encodedClassName);
                _loc7_ = _loc7_.replace("{componentName}",!!classInfo.customSuperClassName?classInfo.customSuperClassName:classInfo.superClassName);
                _loc7_ = _loc7_.replace("{uiPath}","ui://" + publishData.targetUIPackage.id + classInfo.classId);
                _loc7_ = _loc7_.replace("{createInstance}","\t\t\treturn (" + classInfo.encodedClassName + ")UIPackage.CreateObject(\"" + publishData.targetUIPackage.name + "\",\"" + classInfo.className + "\");");
                _loc7_ = _loc7_.split("{uiPkgName}").join(publishData.targetUIPackage.name);
                _loc7_ = _loc7_.split("{uiResName}").join(classInfo.className);
                _loc8_ = 0;
                _loc9_ = 0;
                _loc10_ = 0;
                for each(var memberInfo:Object in classInfo.members)
                {
                    if (classInfo.desc && classInfo.desc.displayList && classInfo.desc.displayList.children().length() > 0)
                    {
                        for (var j:int = 0; j < classInfo.desc.displayList.children().length(); j++)
                        {
                            var desc:XML = classInfo.desc.displayList.children()[j];
                            if (desc.@name == memberInfo.originalName)
                            {
                                var notTouchable:Boolean = desc.@touchable == "false";
                                break;
                            }
                        }
                    }
                    if(memberInfo.type == "Controller")
                    {
                        if(!memberInfo.ignored)
                        {
                            if(settings.getMemberByName)
                            {
                                _loc5_.push("\t\t\t" + memberInfo.name + " = this.GetController(\"" + memberInfo.originalName + "\");");
                            }
                            else
                            {
                                _loc5_.push("\t\t\t" + memberInfo.name + " = this.GetControllerAt(" + _loc9_ + ");");
                            }
                        }
                        _loc9_++;
                    }
                    else if(memberInfo.type == "Transition")
                    {
                        if(!memberInfo.ignored)
                        {
                            if(settings.getMemberByName)
                            {
                                _loc5_.push("\t\t\t" + memberInfo.name + " = this.GetTransition(\"" + memberInfo.originalName + "\");");
                            }
                            else
                            {
                                _loc5_.push("\t\t\t" + memberInfo.name + " = this.GetTransitionAt(" + _loc10_ + ");");
                            }
                        }
                        _loc10_++;
                    }
                    else
                    {
                        if(!memberInfo.ignored)
                        {
                            if(settings.getMemberByName)
                            {
                                _loc5_.push("\t\t\t" + memberInfo.name + " = (" + memberInfo.type + ")this.GetChild(\"" + memberInfo.originalName + "\");");
                            }
                            else
                            {
                                _loc5_.push("\t\t\t" + memberInfo.name + " = (" + memberInfo.type + ")this.GetChildAt(" + _loc8_ + ");");
                            }
                        }
                        _loc8_++;
                    }
                    if(!memberInfo.ignored)
                    {
                        _loc6_.push("\t\tpublic " + memberInfo.type + " " + memberInfo.name + ";");
                    }
                }
                _loc7_ = _loc7_.replace("{variable}",_loc6_.join("\r\n"));
                _loc7_ = _loc7_.replace("{content}",_loc5_.join("\r\n"));
                _loc2_.push("\t\t\tUIObjectFactory.SetPackageItemExtension(" + classInfo.encodedClassName + ".URL, typeof(" + classInfo.encodedClassName + "));");
                UtilsFile.saveString(new File(thisPackageFolder.nativePath + File.separator + classInfo.encodedClassName + ".cs"),GenCodeUtils.FILE_MARK + "\n\n" + _loc7_);
            }
            _loc3_ = thisPackageName + "Binder";
            _loc4_ = param1["Binder"];
            _loc4_ = _loc4_.replace("{packageName}",thisPackagePath);
            _loc4_ = _loc4_.split("{className}").join(_loc3_);
            _loc4_ = _loc4_.replace("{bindContent}",_loc2_.join("\r\n"));
            UtilsFile.saveString(new File(thisPackageFolder.nativePath + File.separator + _loc3_ + ".cs"),GenCodeUtils.FILE_MARK + "\n\n" + _loc4_);
            stepCallback.callOnSuccess();
        }
	}
}